package org.dtrd.modules.drug.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dtrd.modules.drug.entity.bean.DrugCategoryDetail;
import org.dtrd.modules.drug.entity.bean.DrugCategoryInfo;
import org.dtrd.modules.drug.entity.po.DtrdExtEmsYwDrugCategory;
import org.dtrd.modules.drug.entity.request.DrugCategoryListRequest;
import org.dtrd.modules.drug.mapper.DtrdExtEmsYwDrugCategoryMapper;
import org.dtrd.modules.drug.service.IDtrdExtEmsYwDrugCategoryService;
import org.dtrd.common.util.StringUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;


/**
 * <p>
 * 药品分类 服务实现类
 * </p>
 *
 * @author QR
 * @since 2021-12-02
 */
@Service
@DS("multi-datasource1")
public class DtrdExtEmsYwDrugCategoryServiceImpl extends ServiceImpl<DtrdExtEmsYwDrugCategoryMapper, DtrdExtEmsYwDrugCategory> implements IDtrdExtEmsYwDrugCategoryService {

    private final static String defaultCategoryName = "无";

    @Override
    public List<DrugCategoryInfo> getDrugColumnList(DrugCategoryListRequest request) {
        LambdaQueryWrapper<DtrdExtEmsYwDrugCategory> queryWrapper = baseQueryWrapper();
        if (request.getColumnName() != null){
            queryWrapper.like(DtrdExtEmsYwDrugCategory::getCategoryName, StringUtil.fuzzySearchWrapper(request.getColumnName()));
        }
        Integer drugCategoryId = request.getDrugCategoryId();
        if (drugCategoryId != null) {
            queryWrapper.eq(DtrdExtEmsYwDrugCategory::getCategoryPid, drugCategoryId);
        }
        List<DtrdExtEmsYwDrugCategory> poList = list(queryWrapper);
        // 需要把分类 id 对应的分类信息找出来
        if (drugCategoryId != null) {
            DtrdExtEmsYwDrugCategory query = this.getById(drugCategoryId);
            poList.add(query);
        }
        Map<Integer, String> idToName = poList.stream()
                .collect(groupingBy(DtrdExtEmsYwDrugCategory::getDataId, mapping(DtrdExtEmsYwDrugCategory::getCategoryName, joining())));
        List<DrugCategoryInfo> dtoList = new ArrayList<>(poList.size());
        if (!poList.isEmpty()) {
            dtoList = poList.stream()
                .map(po -> {
                    DrugCategoryInfo drugCategoryInfo = new DrugCategoryInfo().parseFromPo(po);
                    // 根据 pid 设置分类名字
                    Integer pid = po.getCategoryPid();
                    if (pid == null) {
                        drugCategoryInfo.setCategoryName(defaultCategoryName);
                    }else {
                        drugCategoryInfo.setCategoryName(idToName.get(pid));
                    }
                    return drugCategoryInfo;
                })
                .collect(toList());
        }
        return dtoList;
    }

    @Override
    public List<Integer> getDrugCategoryIds(Integer categoryId) {
        LambdaQueryWrapper<DtrdExtEmsYwDrugCategory> queryWrapper = baseQueryWrapper()
                .eq(DtrdExtEmsYwDrugCategory::getCategoryPid, categoryId);
        List<DtrdExtEmsYwDrugCategory> poList = this.list(queryWrapper);
        List<Integer> ids = poList.stream()
                .map(DtrdExtEmsYwDrugCategory::getDataId)
                .collect(toList());
        // 加上自己, 有一些分类可能没有子类
        ids.add(categoryId);
        return ids;
    }

    @Override
    public Map<Integer, String> getDrugCategoryIdToName() {
        List<DtrdExtEmsYwDrugCategory> categoryList = this.list();
        return categoryList.stream()
                .collect(groupingBy(DtrdExtEmsYwDrugCategory::getDataId, mapping(DtrdExtEmsYwDrugCategory::getCategoryName, joining())));
    }

    @Override
    public DrugCategoryDetail getDrugCategory(Integer dataId) {
        DtrdExtEmsYwDrugCategory dtrdExtEmsYwDrugCategory = getById(dataId);
        return Optional.ofNullable(dtrdExtEmsYwDrugCategory)
                        .map(po -> {
                            DrugCategoryDetail drugCategoryDetail = new DrugCategoryDetail().parseFromPo(po);
                            if (drugCategoryDetail.getCategoryId() != 0) {
                                Integer categoryId = drugCategoryDetail.getCategoryId();
                                DtrdExtEmsYwDrugCategory category = this.getById(categoryId);
                                drugCategoryDetail.setCategoryName(category.getCategoryName());
                            }
                            return drugCategoryDetail;
                        })
                        .orElse(null);
    }

    @Override
    public boolean saveOrUpdateDrugCategory(DrugCategoryDetail dto) {
        DtrdExtEmsYwDrugCategory dtrdExtEmsYwDrugCategory = new DtrdExtEmsYwDrugCategory();
        if(dto.getDataId() == null){
            dtrdExtEmsYwDrugCategory = dtrdExtEmsYwDrugCategory.init();
        }
        dtrdExtEmsYwDrugCategory.parseFromDto(dto);
        return saveOrUpdate(dtrdExtEmsYwDrugCategory);
    }

    @Override
    public boolean removeDrugCategory(Integer dataId) {
        return removeById(dataId);
    }

    @Override
    public List<DrugCategoryInfo> getDrugCategoryList() {
        // 没有 pid 的分类 category_pid 的值为0
        int noPid = 0;
        LambdaQueryWrapper<DtrdExtEmsYwDrugCategory> queryWrapper = baseQueryWrapper()
                .eq(DtrdExtEmsYwDrugCategory::getCategoryPid, noPid);
        List<DtrdExtEmsYwDrugCategory> poList = this.list(queryWrapper);
        List<DrugCategoryInfo> dtoList = new ArrayList<>(poList.size());
        if (CollectionUtil.isNotEmpty(poList)) {
            dtoList = poList.stream()
                    .map(po -> new DrugCategoryInfo().parseFromPo(po))
                    .collect(Collectors.toList());
        }
        return dtoList;
    }

    private LambdaQueryWrapper<DtrdExtEmsYwDrugCategory> baseQueryWrapper() {
        return Wrappers.lambdaQuery(DtrdExtEmsYwDrugCategory.class)
                        .eq(DtrdExtEmsYwDrugCategory::getIsDel, 0);
    }

    private LambdaUpdateWrapper<DtrdExtEmsYwDrugCategory> baseUpdateWrapper() {
        return Wrappers.lambdaUpdate(DtrdExtEmsYwDrugCategory.class)
                        .eq(DtrdExtEmsYwDrugCategory::getIsDel, 0);
    }
}
